// FM.cpp

#include "StdAfx.h"

#include "../../../../C/Alloc.h"

#include "Common/System/Error.h"
#include "Common/System/MemoryLock.h"

#ifndef UNDER_CE
#include "Common/System/Security.h"
#endif



#include "resource.h"

#include "App.h"
#include "Common/String/FormatUtils.h"
#include "Common/Lang/LangUtils.h"
#include "Panel.h"
#include "Common/Registry/RegistryUtils.h"
#include "Common/String/StringUtils.h"
#include "ViewSettings.h"

using namespace Common;

using namespace Common::System;

CAppModule _Module;

CMainWnd g_App;

#ifdef UNDER_CE
#define WS_OVERLAPPEDWINDOW ( \
  WS_OVERLAPPED   | \
  WS_CAPTION      | \
  WS_SYSMENU      | \
  WS_THICKFRAME   | \
  WS_MINIMIZEBOX  | \
  WS_MAXIMIZEBOX)
#endif


bool IsLargePageSupported()
{
  #ifdef _WIN64
  return true;
  #else
  OSVERSIONINFO versionInfo;
  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
  if (!::GetVersionEx(&versionInfo))
	return false;
  if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5)
	return false;
  if (versionInfo.dwMajorVersion > 5)
	return true;
  if (versionInfo.dwMinorVersion < 1)
	return false;
  if (versionInfo.dwMinorVersion > 1)
	return true;
  // return IsWow64();
  return false;
  #endif
}

#ifndef UNDER_CE
static void SetMemoryLock()
{
  if (!IsLargePageSupported())
	return;
  // if (Registry::ReadLockMemoryAdd())
	Security::AddLockMemoryPrivilege();

  if (Registry::ReadLockMemoryEnable())
	Security::EnableLockMemoryPrivilege();
}
#endif


#define NT_CHECK_FAIL_ACTION MessageBox(0, _T("Unsupported Windows version"), _T("7-zip"), MB_ICONERROR); return 1;


//forward
int Run(HINSTANCE hInstance, LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWDEFAULT);

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
  #ifdef _WIN32

	SetLargePageSize();

  #endif

  //InitCommonControls();


  HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to 
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	int nRet = Run(hInstance, lpstrCmdLine, nCmdShow); //remove hInstance

	_Module.Term();
	::CoUninitialize();

	return nRet;
}


int Run(HINSTANCE hInstance, LPTSTR lpstrCmdLine, int nCmdShow)
{
	/*CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CMainFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}

	wndMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
*/

  // OleInitialize is required for drag and drop.
  #ifndef UNDER_CE
  OleInitialize(NULL);
  #endif
  
  CString commandsString (lpstrCmdLine);

  #ifdef UNDER_CE
  commandsString = GetCommandLineW();
  #else
  CString programString;
  String::SplitStringToTwoStrings(GetCommandLine(), programString, commandsString);
  #endif

  commandsString.Trim();
  CString paramString, tailString;
  String::SplitStringToTwoStrings(commandsString, paramString, tailString);
  paramString.Trim();
  tailString.Trim();
  if (tailString.Left(2) == _T("-t"))
	  g_App.SetArcFormat(tailString.Mid(2));
  if (!paramString.IsEmpty())
  {
	  g_App.SetMainPath(paramString); 
  }
 

  #ifndef UNDER_CE
  SetMemoryLock();
  #endif

  
  CMessageLoop theLoop;
  _Module.AddMessageLoop(&theLoop);

  if (!g_App.CreateThis(/*hInstance, nCmdShow*/))
	return FALSE;

  

	//CMainFrame wndMain;

	//if(wndMain.CreateEx() == NULL)
	//{
	//	ATLTRACE(_T("Main window creation failed!\n"));
	//	return 0;
	//}

	g_App.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	

  #ifndef UNDER_CE
  OleUninitialize();
  #endif
 
  return nRet;
}





